package com.tykboot.controller;

import com.alibaba.fastjson.JSON;
import com.tykboot.core.base.BaseController;
import com.tykboot.core.persistence.Criteria;
import com.tykboot.core.persistence.Restrictions;
import com.tykboot.entity.TbBalance;
import com.tykboot.entity.TbTransaction;
import com.tykboot.message.MsgCode;
import com.tykboot.message.ResponseMsg;
import com.tykboot.service.ITbBalanceService;
import com.tykboot.service.ITbTransactionService;
import com.tykboot.vo.TransactionVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 *  Controller
 *
 * @author LiuYu
 */ 
@Api(tags = "transaction", description = "/api/transactions")
@RestController
@RequestMapping(BaseController.API + "/transactions")
public class TbTransactionController extends BaseController {

	@Autowired
	private ITbTransactionService tbTransactionService;

	@Autowired
	private ITbBalanceService tbBalanceService;

	@ApiOperation(value = "Add an transaction", notes = "Add an transaction")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "financialId", value = "financialId", dataType = "string", paramType = "header", required = true)
	})
	@PostMapping("")
	public ResponseMsg<TbTransaction> add(@RequestHeader("financialId") String financialId,
									  @RequestBody TransactionVo requestBody) {
		ResponseMsg<TbTransaction> responseMsg = new ResponseMsg<>();
		TbTransaction entity = new TbTransaction();
		BeanUtils.copyProperties(requestBody, entity);
		entity.setFinancialId(financialId);
		entity.setAmountDb(JSON.toJSONString(requestBody.getAmount()));
		entity.setBankTransactionCodeDb(JSON.toJSONString(requestBody.getBankTransactionCode()));
		entity.setProprietaryBankTransactionCodeDb(JSON.toJSONString(requestBody.getProprietaryBankTransactionCode()));
		entity.setMerchantDetailsDb(JSON.toJSONString(requestBody.getMerchantDetails()));
		entity = tbTransactionService.save(entity);
		responseMsg.setData(entity);
		return responseMsg;
	}

	@ApiOperation(value = "Update an transaction", notes = "Update an transaction")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "financialId", value = "financialId", dataType = "string", paramType = "header", required = true),
			@ApiImplicitParam(name = "transactionId", value = "transactionId", dataType = "string", paramType = "path", required = true)
	})
	@PutMapping("/{transactionId}")
	public ResponseMsg<TbTransaction> update(@RequestHeader("financialId") String financialId,
										 @PathVariable("transactionId") String transactionId,
										 @RequestBody TransactionVo requestBody) {
		ResponseMsg<TbTransaction> responseMsg = new ResponseMsg<>();
		TbTransaction entity = tbTransactionService.findById(transactionId);
		if (entity == null) {
			return new ResponseMsg<>(MsgCode.Param_Error);
		}
		BeanUtils.copyProperties(requestBody, entity, "transactionId");
		entity.setFinancialId(financialId);
		entity.setAmountDb(JSON.toJSONString(requestBody.getAmount()));
		entity.setBankTransactionCodeDb(JSON.toJSONString(requestBody.getBankTransactionCode()));
		entity.setProprietaryBankTransactionCodeDb(JSON.toJSONString(requestBody.getProprietaryBankTransactionCode()));
		entity.setMerchantDetailsDb(JSON.toJSONString(requestBody.getMerchantDetails()));
		entity = tbTransactionService.save(entity);
		responseMsg.setData(entity);
		return responseMsg;
	}

	@ApiOperation(value = "Get Transactions", notes = "Get Transactions")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "financialId", value = "financialId", dataType = "string", paramType = "header", required = true)
	})
	@GetMapping("")
	public ResponseMsg<List<TbTransaction>> queryTransactions(@RequestHeader("financialId") String financialId) {
		ResponseMsg<List<TbTransaction>> responseMsg = new ResponseMsg<>();
		Criteria<TbTransaction> req = new Criteria<>();
		req.add(Restrictions.eq("financialId", financialId));
		List<TbTransaction> list = tbTransactionService.findAll(req);
		if (list != null && !list.isEmpty()) {
			for(TbTransaction model : list) {
				Criteria<TbBalance> criteria2 = new Criteria<>();
				criteria2.add(Restrictions.eq("accountId", model.getAccountId()));
				criteria2.add(Restrictions.eq("financialId", financialId));

				List<TbBalance> tbBalances = tbBalanceService.findAll(criteria2);
				if (tbBalances != null && !tbBalances.isEmpty()) {
					model.setBalance(tbBalances.get(0));
				}
			}
			responseMsg.setData(list);
		}
		return responseMsg;
	}

	@ApiOperation(value = "Get account Transactions", notes = "Get Transactions related to an account")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "financialId", value = "financialId", dataType = "string", paramType = "header", required = true),
			@ApiImplicitParam(name = "accountId", value = "accountId", dataType = "string", paramType = "path", required = true)
	})
	@GetMapping("/{accountId}")
	public ResponseMsg<List<TbTransaction>> queryTransactionsById(@RequestHeader("financialId") String financialId,
																  @PathVariable("accountId") String accountId) {
		ResponseMsg<List<TbTransaction>> responseMsg = new ResponseMsg<>();
		Criteria<TbTransaction> req = new Criteria<>();
		req.add(Restrictions.eq("accountId", accountId));
		req.add(Restrictions.eq("financialId", financialId));
		List<TbTransaction> list = tbTransactionService.findAll(req);
		if (list != null && !list.isEmpty()) {
			for(TbTransaction model : list) {
				Criteria<TbBalance> criteria2 = new Criteria<>();
				criteria2.add(Restrictions.eq("accountId", accountId));
				criteria2.add(Restrictions.eq("financialId", financialId));

				List<TbBalance> tbBalances = tbBalanceService.findAll(criteria2);
				if (tbBalances != null && !tbBalances.isEmpty()) {
					model.setBalance(tbBalances.get(0));
				}
			}
			responseMsg.setData(list);
		}
		return responseMsg;
	}

}
